home *** CD-ROM | disk | FTP | other *** search
- /* fraction.c */
- /* Copyright 1992 by P.J. LaBrocca */
-
- #include <stdio.h>
- #include "mixed.h"
-
- mixed_t *mix_init( mixed_t *m, Integer w, Integer n, Integer d )
- {
- m->sign = POSITIVE;
- m->whole = w;
- if( w < 0 ) {
- m->sign = NEGATIVE;
- m->whole *= -1;
- }
- m->num = n;
- m->den = d;
- m->factors[ NUMER ][ 0 ] = 1;
- m->factors[ DENOM ][ 0 ] = 1;
- return m;
- }
-
- mixed_t *mix_clear( mixed_t *m )
- {
- m->whole = 0;
- m->num = 0;
- m->den = 1;
- m->factors[ NUMER ][ 0 ] = 1;
- m->factors[ DENOM ][ 0 ] = 1;
- m->sign = POSITIVE;
- return m;
- }
-
- mixed_t *mix_factor( mixed_t *m )
- {
- Integer n;
- int i;
- Integer *pi;
- Integer *pp;
-
- for( i = 0; i < 2; ++i) {
- pp = Primes; /* point to global array of primes */
- (i != 0) ? (n = m->den) : (n = m->num);
- pi = &m->factors[i][0];
-
- while(n > 1) {
- if( !(n % *pp) ) { /* if there is no remainder */
- n = (Integer) (n / *pp); /* factor the prime out of number */
- *pi = *pp; /* save the prime */
- ++pi;
- continue; /* try the prime again */
- }
- ++pp; /* next prime */
- }
- *pi = 1;
- pp = Primes;
- }
- return m;
- }
-
- mixed_t *mix_reduce( mixed_t *m )
- {
- Integer tnum = 1, tden = 1;
- Integer *top = &m->factors[NUMER][0];
- Integer *bot = &m->factors[DENOM][0];
-
- if( m->num == 0) {
- return m;
- }
- if( m->den == 1 ) {
- m->whole += m->num;
- m->num = 0;
- return m;
- }
- mix_factor( m ); /* got to factor to reduce */
- /*accumulators for reduced numerator & denominator*/
- while(*top != 1 && *bot != 1) { /* neither factor is sentinel */
- if(*top == *bot) { /* if the current factors are equal..*/
- ++top; /* ..cancel them & continue */
- ++bot;
- continue;
- } /* otherwise accumulate the smaller*/
- (*top < *bot) ? (tnum *= *top++) : (tden *= *bot++);
-
- }
- while(*top != 1) /* any remaining factors are */
- tnum *= *top++; /* multiplied in */
- while(*bot != 1)
- tden *= *bot++;
- if(tnum == tden) { /*ie, n/d == 1*/
- ++m->whole; /*add 1 to whole*/
- m->num = 0;
- m->den = 1;
- }
- else if(tnum > tden) { /*improper fraction*/
- m->whole += (Integer) (tnum / tden);
- m->num = tnum % tden;
- m->den = tden;
- }
- else { /*proper fraction*/
- m->num = tnum;
- m->den = tden;
- }
- if(m->num == 0) { /* keep zero-valued fractions*/
- m->den = 1; /* in consistent state*/
- if(m->whole == 0)
- mix_clear( m );
- }
- return m;
- }
-
- void mix_make_improper( mixed_t *m ) /* converts invoking instance*/
- { /* into an improper fraction*/
- m->num += m->whole * m->den; /* if possible*/
- m->whole = 0;
- }
-
- /* If sizeof( Integer ) changes
- change %ld
- */
- void mix_print( mixed_t *m )
- {
- printf("\t");
- if( m->sign == -1 )
- printf("-");
- if( m->whole != 0 )
- printf("%ld", m->whole);
- if( m->num != 0 )
- printf(" %ld|%ld",m->num, m->den);
- if( (m->whole == 0) && (m->num == 0) )
- printf("0");
- printf("\n");
- }
-
-